package com.soo.hoo.admin.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.soo.hoo.admin.model.dto.RoleDTO;
import com.soo.hoo.admin.model.entity.SysRole;
import com.soo.hoo.admin.model.vo.RoleVO;
import com.soo.hoo.admin.service.PermissionService;
import com.soo.hoo.admin.service.RolePermissionService;
import com.soo.hoo.admin.service.RoleService;
import com.soo.hoo.core.exception.GlobalException;
import com.soo.hoo.core.model.KeyValue;
import com.soo.hoo.core.model.Page;
import com.soo.hoo.core.model.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色管理
 * </p>
 *
 * @author 杨燚
 * @since 2023-04-11
 */
@Tag(name = "角色管理")
@RequestMapping("/role/")
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class RoleController {

    private final RoleService roleService;
    private final PermissionService permissionService;
    private final RolePermissionService rolePermissionService;

    @Operation(summary = "角色列表")
    @GetMapping("list")
    public Result<List<KeyValue>> list() {
        List<SysRole> list = roleService.list();
        List<KeyValue> vos =
                list.stream().map(
                        e -> KeyValue.builder().key(e.getId()).value(e.getRoleName()).build()
                ).toList();
        return Result.success(vos);
    }

    @Operation(summary = "角色分页")
    @PostMapping("page")
    public Result<Page<RoleVO>> page(@RequestBody Page<SysRole> param) {
        Page<SysRole> page = roleService.page(param);
        Page<RoleVO> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal(), page.getPages(), null);
        if (CollUtil.isNotEmpty(page.getRecords())) {
            Set<Long> roleIds = page.getRecords().stream().map(SysRole::getId).collect(Collectors.toSet());
            Map<Long, RoleDTO> rolePermissionMap = permissionService.mapRolePermission(roleIds);
            List<RoleVO> vos = new ArrayList<>();
            for (SysRole record : page.getRecords()) {
                RoleVO vo = new RoleVO();
                BeanUtil.copyProperties(record, vo);
                RoleDTO dto = rolePermissionMap.get(record.getId());
                vo.setPermissionIds(dto == null ? null : dto.getPermissionIds());
                vo.setPermissionNames(
                        dto == null ? null
                                : CollUtil.isEmpty(dto.getPermissionNames()) ? null
                                : String.join("、", dto.getPermissionNames())
                );
                vos.add(vo);
            }
            voPage.setRecords(vos);
        }
        return Result.success(voPage);
    }

    @Operation(summary = "新建角色")
    @PostMapping("create")
    public Result<Void> create(@RequestBody @Valid RoleDTO param) {
        SysRole sysRole = new SysRole();
        BeanUtil.copyProperties(param, sysRole);
        sysRole.setSuperRole(false);
        roleService.save(sysRole);
        rolePermissionService.saveRelevance(sysRole.getId(), param.getPermissionIds());
        return Result.success();
    }

    @Operation(summary = "编辑角色")
    @PostMapping("update")
    public Result<Void> update(@RequestBody @Valid RoleDTO param) {
        if (param.getId() == null) {
            throw new GlobalException("编辑失败：【编辑时id字段不能为空】");
        }
        SysRole byId = roleService.getById(param.getId());
        if (byId.getSuperRole()) {
            throw new GlobalException("超级管理员不支持编辑操作");
        }
        if (!byId.getRoleName().equals(param.getRoleName())) {
            roleService.verifyRole(param.getRoleName());
        }
        SysRole sysRole = new SysRole();
        BeanUtil.copyProperties(param, sysRole);
        sysRole.setSuperRole(byId.getSuperRole());
        roleService.updateById(sysRole);
        rolePermissionService.deleteByRoleId(param.getId());
        rolePermissionService.saveRelevance(param.getId(), param.getPermissionIds());
        return Result.success();
    }

    @Operation(summary = "删除角色")
    @DeleteMapping("delete")
    public Result<Void> delete(@RequestParam Long id) {
        SysRole role = roleService.getById(id);
        if (role.getSuperRole()) {
            throw new GlobalException("超级管理员不支持删除操作");
        }
        roleService.removeById(id);
        return Result.success();
    }
}
